package com.zoe.onelink.feign.resolver;

import cn.hutool.core.util.StrUtil;
import com.netflix.client.ClientException;
import com.zoe.onelink.common.entity.ResultVO;
import com.zoe.onelink.core.exception.ExceptionResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.i18n.LocaleContextHolder;

import java.util.Locale;

/**
 * <p>标题: Feign异常处理器</p>
 * <p>描述: Feign异常包含两类
 * 1: 请求已经发送出去,提供者出现异常,此时会走ErrorDecoder
 * 2: 请求没有发出去就发生异常,例如找不到提供者,此时会走默认的全局异常处理,这里实现core提供的processor进行异常处理
 * </p>
 * <p>版权: Copyright (c) 2022</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2022-03-23
 */
@RequiredArgsConstructor
public class FeignExceptionResolver implements ExceptionResolver {

    public static final String PROVIDER_EX_PREFIX = "Load balancer does not have available server for client";

    @Override
    public boolean couldResolve(Throwable ex) {
        return ex instanceof ClientException || ex.getCause() instanceof ClientException;
    }

    @Override
    public ResultVO<Object> resolve(Throwable ex) {
        ClientException clientException = (ClientException) (ex instanceof ClientException ? ex : ex.getCause());
        if (clientException.getMessage() == null) {
            return null;
        }
        Locale locale = LocaleContextHolder.getLocale();
        ResultVO<Object> resultVO;
        LocaleContextHolder.getLocale();
        if (clientException.getMessage().startsWith(PROVIDER_EX_PREFIX)) {
            String errMsg;
            if (Locale.CHINA.equals(locale) || Locale.CHINESE.equals(locale)) {
                String serviceName = clientException.getMessage().substring(PROVIDER_EX_PREFIX.length() + 2);
                errMsg = StrUtil.format("没有可用的服务节点，请检查服务【{}】是否在注册中心Nacos的服务列表中以及服务是否正常启动", serviceName);
            } else {
                errMsg = clientException.getMessage();
            }
            resultVO = ResultVO.failure(errMsg);
        } else {
            resultVO = null;
        }
        return resultVO;
    }

}
